
//Monster delay is how often monsters move on their own when far away from players
#define MONSTER_DELAY 60

TurnController
	MonsterController
		var
			LevelController/LevelController
			zlevel as num
			cMonsters // Counter for number of monsters on this level
		New(_zlevel as num)
			if(!_zlevel) del src
			pcList = null
			pcWithMove = null
			LevelController = LevelControllers[_zlevel]
			zlevel = _zlevel
			spawn(10) MonsterLoop()
			return 1
		AddMob(mob/M as mob)
			if(istype(M,/mob/pc)) return 0
			npcList.Add(M)
			if(M.TurnController) M.TurnController.RemoveMob(M)
			M.TurnController = src
		RemoveMob(mob/M as mob)
			if(istype(M,/mob/pc)) return 0
			npcList.Remove(M)
		proc
			MonsterLoop()
				set background=1
				while(1)
					for(var/mob/monster/M in npcList)
						M.AIMove()
					sleep(MONSTER_DELAY)

			MonsterDeath(mob/monster/M as mob)
				cMonsters -= 1
				src.RemoveMob(M)

			MonsterBirth(mob/monster/M as mob)
				cMonsters += 1
				src.AddMob(M)

			SpawnMonsters()
				var/bRunning = True
				while(bRunning)
					if(prob(80))
						AddMonsterToLevel()
					else
						bRunning = False

/* First, if a particular monType and subType were not specified(-1 or 0 for random)
randomly choose a monster depending on the dungeon level.
Then, create the monster and give it some loot */
			CreateMonster(turf/loc, wDifficulty, monType, subType)
				var/hp, ndice, idie;
				if(wDifficulty==0)
					wDifficulty=1
				if(monType == -1 || subType == -1)
					// ****FIX ME****
					wDifficulty = src.zlevel + 1 - DUNGEON_INIT // Fudging the difficulty.
					// Having difficulties tracking it down in the original CotW
					var/mLevel = MonLevelFromLevel(wDifficulty)
				//#ifdef REVIEW
					var/list/L = mpRandMonMst[mLevel]
					subType = pick(L) // Get a random monster*/

// Commented out due to Idstr
				//if (subType == -1)
		//	Restart:
				//	subType = mpMtStFirst[monType] + rand(mpMtStMax[monType])
			//		if (IdstrFromMst(subType, fFalse) == 0)
			//			goto Restart;	// NYI

				//var/mob/monster/M
				//var/monPath
				//for(var/i in AllMonsters)
				//	if(

				var/mob/monster/M = new subType(loc)
				if(!M) return NULL
				hp = M.hp	/* init data is like this */
				ndice = M.hpMax;
				for (idie = 0; idie < ndice; idie++)
					hp += rand(6);

				M.hpMax = hp
				M.hp = M.hpMax
				/* Does the monster have treasure? */
				/*
				if (pmonster->hobjlist && (random(4) || (monType == mtSpecial)))
					{	/* yes, hobjlist has the treasure type */
					int ttype = (int)pmonster->hobjlist;
					int subType;
					if ((pmonster->hobjlist = AllocObjlist()) != NULL)
						{
						HOBJECT hobject;
						HOBJLIST hobjlist;
						int iObj;
						switch (ttype)
							{
							case montreasureObject:
							case montreasure2Objects:
							case montreasure3Objects:
							case montreasure4Objects:
							case montreasure5Objects:
								{
								for (iObj = 0; iObj < ttype; iObj++)
									{
									if (hobject = CreateObj(rgscene[sceneCur].wDifficulty, objNull, subNull, fFalse))
										{
										if (!FAddObjToObjlist(hobject,
											pmonster->hobjlist , -1, fFalse))
											{
											DeleteObj(hobject);
											break;
											}
										}
									}
								break;
								}
							case montreasureCopper:
							case montreasureSilver:
							case montreasureGold:
							case montreasurePlatinum:
								subType = ttype - montreasureCopper + treasureCopper;
								goto CreateMonTreasure;
							case montreasureCoins:
								subType = subNull;	/* random */
			CreateMonTreasure:
								if (hobject = CreateObj(rgscene[sceneCur].wDifficulty,
									objTreasure, subType, fFalse))
									{
									if (!FAddObjToObjlist(hobject,
										pmonster->hobjlist , -1, fFalse))
										{
										DeleteObj(hobject);
										}
									}
								break;
							case montreasureGiant:
								// 50% chance of Shield
								if (random(2) && (hobject = CreateObj(rgscene[sceneCur].wDifficulty, objShield, subNull, NULL)))
									{
									if (!FAddObjToObjlist(hobject,
										pmonster->hobjlist , -1, fFalse))
										{
										DeleteObj(hobject);
										break;
										}
									}
								// 50% chance of large bag
								if (random(2) && (hobjlist = (HOBJLIST)CreateObj(rgscene[sceneCur].wDifficulty,
									objContainer, containerLargeBag, coAllowContents)))
									{
									if (!FAddObjToObjlist((HOBJECT)hobjlist,
										pmonster->hobjlist , -1, fFalse))
										{
										DeleteObj((HOBJECT)hobjlist);
										break;
										}
									}
								else
									hobjlist = NULL;
								for (iObj = 0; iObj < 2; iObj++)
									{
									if (hobject = CreateObj(rgscene[sceneCur].wDifficulty,
										objNull, subNull, fFalse))
										{
										if (!FAddObjToObjlist(hobject,
											hobjlist ? hobjlist : pmonster->hobjlist , -1, fFalse))
											{	// may not fit in bag. Try regular objlist
											if (hobjlist && !FAddObjToObjlist(hobject,
												pmonster->hobjlist , -1, fTrue))
												{
												DeleteObj(hobject);
												break;
												}
											}
										}
									}
								break;
							}
						}

					}
				else
					pmonster->hobjlist = NULL;*/
				return M


/*
			CreateMonster(loc)
				if(cMonsters > 30)
					return False
				var/monsterType = pick(AllMonsters)
			//	var/mob/monster/M = new monsterType(null)
				new monsterType(loc)
			//	while(!M.loc)
			//		var/turf/T = locate(rand(1,50), rand(1,50), zlevel)
			//		if(T && T.Enter(M))
			//			M.loc = T
			//	MonsterBirth(M)
*/

			CreateMonsterAtLoc(turf/loc, monType, subType, wFlags)
				var/mob/monster/M = CreateMonster(loc, zlevel, monType, subType) // Check zlevel arg passed in CotW
				if(M)
					if(wFlags & cmAwake)
						SetMonStat(M, mstatAwake)
					else if(wFlags & cmAsleep)
						ResetMonStat(M, mstatAwake)
					else if(M.monType == mtBlob || rand(2))
						SetMonStat(M, mstatAwake) // blobs don't sleep!
					else
						ResetMonStat(M, mstatAwake)
					M.loc = loc
					MonsterBirth(M)


			AddMonsterToLevel()
				var/LocFound
				var/turf/T
				var/list/turflist = block(locate(1,1,zlevel), locate(50,50,zlevel))
				while(!LocFound && turflist.len)
					T = pick(turflist)
					turflist.Remove(T)
					if(T && !(T.GetDenseObject()))
						LocFound = 1
				if(LocFound)
					CreateMonster(T, -1, -1, 0) /* random monster */

			PopulateLevel()
				var/cMon = 5 + rand(zlevel) // Check the arg passed to rand in CotW
				while(cMon--)
					AddMonsterToLevel()